<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<style>
  html,
  body {
    margin: 0px;
    width: 100%;
    height: 100%;
  }

  div input {
    width: 80px;
    border: 2px solid #e087b1;
    border-radius: 10px;
    text-align: center;
  }

  div span{
    margin-left: 10px;
  }
  div{
    display: flex;
    flex-wrap: wrap;
  }
</style>

<body>
  <div>
    <button id="clear">清空</button>
    <span>数量：<input type="text" id="num" /></span>
    <span>大小：<input type="text" id="size" /></span>
    <span style="display: flex;">填充：<input name="isfill" type="checkbox" id="fill" style="width: 20px;height: 20px;" /></span>
  </div>
  <canvas id="c1" height="500px" width="800px"></canvas>
  <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
  <script>
    window.onload = function () {
      var oC = document.getElementById("c1");
      var clear = document.getElementById("clear");
      var oCG = oC.getContext('2d');
      reSize();
      var mouseX;
      var mouseY;
      var main;
      var length;
      var size;
      oC.onmousedown = function (ev) {
        $("input").blur();
        mouseX = ev.clientX - oC.offsetLeft;
        mouseY = ev.clientY - oC.offsetTop;
        window.clearInterval(main);
        run();
        document.onmousemove = function (ev) {
          mouseX = ev.clientX - oC.offsetLeft;
          mouseY = ev.clientY - oC.offsetTop;
        }
        document.onmouseup = function (ev) {
          document.onmousemove = null;
          document.onmouseup = null;
        }
      };

      oC.ontouchstart = function (ev) {
        $("input").blur();
        ev.preventDefault();
        mouseX = ev.touches[0].clientX - oC.offsetLeft;
        mouseY = ev.touches[0].clientY - oC.offsetTop;
        window.clearInterval(main);
        run();
        document.ontouchmove = function (ev) {
          mouseX = ev.touches[0].clientX - oC.offsetLeft;
          mouseY = ev.touches[0].clientY - oC.offsetTop;
        }
        document.ontouchend = function (ev) {
          ev.preventDefault();
          document.ontouchmove = null;
          document.ontouchend = null;
        }
      };

      clear.onclick = function (ev) {
        window.clearInterval(main);
        clearCan();
      }

      function Lizi(x, y, r) {
        this.x = x;
        this.y = y;
        this.r = r;
      }

      var lizilist = [];
      function run() {
        //判断数量表单
        if($('#num').val()){
          length = $('#num').val()
        }else{
          length = 100;
        }
        //判断大小表单
        if($('#size').val()){
          size = $('#size').val()
        }else{
          size = 10;
        }

        //计数器
        var count = 0;
        //粒子集合
        var lizilist = [];
        //添加粒子对象
        for (let index = 0; index < length; index++) {
          let lizi = new Lizi(mouseX, mouseY, 1 + index*((size-1)/(length-1)));
          lizilist.push(lizi);
        }

        window.clearInterval(main);
        main = setInterval(() => {
          clearCan();
          count++;
          if (count % 10 == 0) {
            let t;
            let temp;
            let yt;
            let tempy;
            //将后一个对象的坐标给前一个对象
            for (let index = lizilist.length - 1; index >= 0; index--) {
              if (index == lizilist.length - 1) {
                t = lizilist[index].x;
                yt = lizilist[index].y;
              } else {
                temp = lizilist[index].x;
                lizilist[index].x = t;
                t = temp;
                tempy = lizilist[index].y;
                lizilist[index].y = yt;
                yt = tempy;
              }
            }
          }

          //画粒子集合
          for (let index = lizilist.length - 1; index > 0; index--) {
            if (index == lizilist.length - 1) {
              lizilist[index].x = mouseX;
              lizilist[index].y = mouseY;
            }
            let item = lizilist[index];
            if (mouseX && mouseY) {
              drawArc(item.x, item.y, item.r);
            }
          }

        }, 1);
      }
      //画粒子
      function drawArc(x, y, r) {
        oCG.beginPath();
        var gradient = oCG.createLinearGradient(0, 0, 800, 0);
        gradient.addColorStop("0", "magenta");
        gradient.addColorStop("0.15", "cyan");
        gradient.addColorStop("0.3", "orange");
        gradient.addColorStop("0.45", "red");
        gradient.addColorStop("0.6", "yellow");
        gradient.addColorStop("0.75", "blue");
        gradient.addColorStop("1.0", "red");
        oCG.strokeStyle = gradient;
        oCG.lineWidth = 5;
        oCG.arc(x, y, r, 0, 2 * Math.PI);
        oCG.fillStyle = gradient;
        //判断填充表单
        if($("#fill").prop('checked')){
          oCG.fill();
        }
        oCG.stroke();
      }

      function clearCan() {
        var oC = document.getElementById("c1");
        var oCG = oC.getContext('2d');
        oC.height = oC.height;
      }

      function log(msg) {
        console.log(msg);
      }

      function resizeCanvas() {
        $(oC).attr("width", $(window).get(0).innerWidth);
        $(oC).attr("height", $(window).get(0).innerHeight);
      };

      function reSize() {
        $(window).resize(resizeCanvas);
        resizeCanvas();
      }
    };
  </script>
</body>

</html>